package co.fitstart.coach.web.controller;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.DateUtils;
import com.demo2do.core.utils.JsonUtils;

import co.fitstart.coach.entity.rest.ArrangePrepare;
import co.fitstart.coach.entity.security.Login;
import co.fitstart.coach.service.CoachRestCalendarService;
import co.fitstart.coach.service.CourseService;
import co.fitstart.coach.service.PrincipalService;
import co.fitstart.coach.web.resolver.Secure;
import co.fitstart.entity.coach.CoachRestType;
import co.fitstart.entity.principal.Principal;
import co.fitstart.entity.site.Site;

/**
 * 
 * @author mohanlan
 *
 */
@Controller
@RequestMapping("/rest-calendars")
public class CoachRestCalendarController {
    
    private static final Logger logger = LoggerFactory.getLogger(CoachRestCalendarController.class);
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private CoachRestCalendarService coachRestCalendarService;
    
    @Autowired
    private CourseService courseService;
    
    /**
     * 
     * @param login
     * @param type
     * @param day
     * @return
     */
    @RequestMapping(value = "/arrange", method = RequestMethod.GET)
    public ModelAndView arrange(@Secure Login login,
                               @RequestParam("day") @DateTimeFormat(pattern = "yyyy-MM-dd") Date day) {
        
        ModelAndView modelAndView = new ModelAndView("rest/rest-calendar-create");
        
        Principal principal = principalService.load(Principal.class, login.getId());
        Site site = principalService.decideSite(principal);
        
        // 1: init arrangePrepare
        ArrangePrepare arrangePrepare = new ArrangePrepare(principal.getId(), day);
        arrangePrepare.init();
        
        // 2: init arrange selector
        List<String> restCalendars = coachRestCalendarService.getDailyCoachRestCalendar(principal, day, CoachRestType.REST);
        List<String> experienceCalendars = coachRestCalendarService.getDailyCoachRestCalendar(principal, day, CoachRestType.EXPERIENCE);
        List<String> dutyCalendars = coachRestCalendarService.getDailyCoachRestCalendar(principal, day, CoachRestType.DUTY);
        List<String> avaliableHours = courseService.listAvaliableTimes(principal, site, day);
        arrangePrepare.initSelectItem(restCalendars, experienceCalendars, dutyCalendars, avaliableHours);

        // 3: init selector limit
        int restCalendarSum = coachRestCalendarService.sumWeeklyCalendar(principal, day, CoachRestType.REST);
        arrangePrepare.initSelectLimit(site, restCalendarSum);
        
        modelAndView.addAllObjects(arrangePrepare.describe());
        return modelAndView;
    }

    /**
     * Arrange rest calendar for single day
     * 
     * @param login
     * @param day
     * @param type
     * @param restLimit
     * @param restSum
     * @param arrangeHours
     * @return
     */
    @RequestMapping(value = "/arrange", method = RequestMethod.POST)
    public @ResponseBody String onArrange(@Secure Login login,
                                          @RequestParam("day") @DateTimeFormat(pattern = "yyyy-MM-dd") Date day,
                                          @RequestParam("coachRestType") String type,
                                          @RequestParam("restLimit") int restLimit,
                                          @RequestParam("restSum") int restSum,
                                          @RequestParam("arrangeHours") List<String> arrangeHours) {
        
        Result result = new Result();
        
        try {
            
            Principal principal = principalService.load(Principal.class, login.getId());
            
            CoachRestType coachRestType = CoachRestType.aliasOf(type);
            
            // validate rest type calendar's limit
            if(login.getId() != 13 && coachRestType.equals(CoachRestType.REST)) {
                coachRestCalendarService.validateSum(restLimit, restSum, arrangeHours.size());
            }
            
            coachRestCalendarService.arrange(principal, coachRestType, day, arrangeHours);
            
            result.success().message("添加休息时间成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("#onArrange() error ", e);
            
            result.fail().message("添加休息时间失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * Cancel rest calendar for single day
     * 
     * @param login
     * @param day
     * @param type
     * @param restLimit
     * @param restSum
     * @param disableHours
     * @return
     */
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public @ResponseBody String onCancel(@Secure Login login,
                                          @RequestParam("day") @DateTimeFormat(pattern = "yyyy-MM-dd") Date day,
                                          @RequestParam("coachRestType") String type,
                                          @RequestParam("disableHours") List<String> disableHours) {
        
        Result result = new Result();
        
        try {
            
            Principal principal = principalService.load(Principal.class, login.getId());
            
            CoachRestType coachRestType = CoachRestType.aliasOf(type);
            
            coachRestCalendarService.cancel(principal, coachRestType, day, disableHours);
            
            result.success().message("删除休息时间成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("#onCancel() error ", e);
            
            result.fail().message("删除休息时间失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param login
     * @param startDate
     * @return
     */
    @RequestMapping(value = "/copy", method = RequestMethod.POST)
    public @ResponseBody String onCopy(@Secure Login login,
                                       @RequestParam(value = "start", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate) {
        Result result = new Result();
        
        try {
            
            Principal principal = principalService.load(Principal.class, login.getId());
            
            Date monday = DateUtils.getFirstWeekDay(startDate);
            
            coachRestCalendarService.copyLastWeek(principal, monday);
            
            result.success().message("复制上周休息时间成功");
            
        } catch (BusinessException e) {
            
            logger.error("#onArrange() error ", e);
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("#onArrange() error ", e);
            result.fail().message("复制上周休息时间失败");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param login
     * @param startDate
     * @return
     */
    @RequestMapping(value = "/clear", method = RequestMethod.POST)
    public @ResponseBody String onClear(@Secure Login login,
                                       @RequestParam(value = "start", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate) {
        Result result = new Result();
        
        try {
            
            Principal principal = principalService.load(Principal.class, login.getId());
            
            Date monday = DateUtils.getFirstWeekDay(startDate);
            
            coachRestCalendarService.clearThisWeek(principal, monday);
            
            result.success().message("清除本周休息时间成功");
            
        } catch (Exception e) {
            
            logger.error("#onClear() error ", e);
            result.fail().message("清除本周休息时间失败");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
}
